{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 感知器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 基本原理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "感知器（Perceptron）由 Frank Roseblatt 于 1957 年提出，是一种广泛使用的线性分类器．感知器可谓是最简单的人工神经网络，只有一个神经元。\n",
    "\n",
    "感知机用如下函数表示\n",
    "$$\n",
    "f(x)=sign({\\boldsymbol{\\omega x}+b})\\tag {1}\n",
    "$$\n",
    "其中$\\boldsymbol{\\omega}$为权重向量，$b$为偏置，$sign$为符号函数，可以将式子中的线性运算结果映射到-1或+1。\n",
    "\n",
    "给定一个数据集，如果存在一个超平面可以把这个数据集完全划分为两个部分，则称为该数据集是线性可分的，而感知机的任务就是找到这样的一个超平面。使得有\n",
    "$$\n",
    "\\left\\{\\begin{aligned}\n",
    "\\boldsymbol{\\omega x_i}+b>0,\\forall y_i=+1\\\\\n",
    "\\boldsymbol{\\omega x_i}+b<0,\\forall y_i=-1\n",
    "\\end{aligned}\\right.\\tag {2}\n",
    "$$\n",
    "感知机的学习策略就是通过定义经验（损失）函数，然后使损失函数极小化以求得相应的$\\boldsymbol{\\omega}$和$b$。将上面式子(2)中的两个式子进行统一可以得到下面的式子\n",
    "$$\n",
    "y_i\\times(\\boldsymbol{\\omega x_i}+b)>0\\tag {3}\n",
    "$$\n",
    "上面的式子(3)是我们希望学得的目标，但是如何学得这个目标，首先需要定义一个损失函数。假设误分类点集合为$M$，即对于误分类点有$y_i\\times(\\boldsymbol{\\omega x_i}+b)<0$，有下面误分类点到超平面的总距离公式：\n",
    "$$\n",
    "L(\\boldsymbol{\\omega},b)=-\\frac{1}{||\\boldsymbol{\\omega}||}\\sum_{\\boldsymbol{x}_i\\in M}y_i(\\boldsymbol{\\omega x}_i+b)\\tag{4}\n",
    "$$\n",
    "所以说，感知机的优化目标就是使得上式(4)中的$L(\\boldsymbol{\\omega},b)$最小。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 感知器算法实现步骤："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 给定初始值:给每个权向量赋任意值\n",
    "\n",
    "2. 输入训练样本进行训练\n",
    "\n",
    "3. 计算判别函数的判别值\n",
    "\n",
    "4. 修改权向量$W(k)$,修正规则如下：\n",
    "      - 若$d(Xi)\\leq0$, 则$W(k+1) = W(k)+ \\rho * y_i * X_i$\n",
    "      - $\\rho$为大于0的一常数(一般取$0<\\rho\\leq1$)\n",
    "      - 否则$W(k+1) = W(k)$\n",
    "5. 当W对所有训练样本均稳定不变时，则结束。否则令$k=k+1$,返回步骤2."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 鸢尾花数据集分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']  # 加入一行，解决中文不显示问题，对应字号选择如下图\n",
    "plt.rcParams['axes.unicode_minus'] = False  # 解决负号不显示问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = datasets.load_iris()  # 加载鸢尾花数据集\n",
    "irisFeature = iris.data      # 鸢尾花数据集数据集及其属性\n",
    "irisTarget = iris.target     # 鸢尾花数据集的标签"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 选择前两种鸢尾花的第二个及第三个特征进行实验   花萼宽度  花瓣长度\n",
    "x = irisFeature[irisTarget < 2, 1:3]  \n",
    "y = irisTarget[irisTarget < 2]\n",
    "for i in range(len(y)):\n",
    "    if y[i] == 0:\n",
    "        y[i] = -1  # 将第一种鸢尾花的标签从0改成-1，便于分类计算\n",
    "# 将数据集进行训练集和测试集划分\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=100)   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构建判别函数\n",
    "def fsign(x, w, b):\n",
    "    y = np.dot(x, w) + b\n",
    "    return y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(x_train, y_train):\n",
    "    iterations = 150   # 迭代次数150\n",
    "    w = [0, 0]         # 初始化权重\n",
    "    b = 0              # 初始化偏置\n",
    "    l_rate = 0.01      # 初始化学习率\n",
    "    for i in range(iterations):\n",
    "        for d in range(len(x_train)):\n",
    "            X = x_train[d]\n",
    "            y = y_train[d]\n",
    "            if y * fsign(X, w, b) <= 0:\n",
    "                w = w + l_rate * np.dot(y, X)  # 更新权重\n",
    "                b = b + l_rate * y  # 更新偏置\n",
    "    return w, b   # 训练得到权重和偏置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(x_test, y_test, weight, b):\n",
    "    wrong = 0\n",
    "    for d in range(len(x_test)):  # 遍历所有测试样本\n",
    "        X = x_test[d]\n",
    "        y = y_test[d]\n",
    "        if y * fsign(X, weight, b) <= 0:\n",
    "            wrong += 1\n",
    "    acc = 1 - wrong / len(x_test)  # 计算正确率\n",
    "    return acc\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.044  0.049] -0.01\n",
      "准确率为:100.0%\n"
     ]
    }
   ],
   "source": [
    "weight, b = train(x_train, y_train)\n",
    "print(weight, b)  # 输出权重和偏置\n",
    "acc = test(x_test, y_test, weight, b)\n",
    "print(f\"准确率为:{acc * 100}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = -weight[0] / weight[1]   # 分界线斜率\n",
    "xx = np.linspace(1.5, 5)\n",
    "yy = a * xx - b / weight[1]  # 分界线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 700x500 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(7,5),dpi=100)\n",
    "for i in range(len(y)):\n",
    "    if irisTarget[i] == 1:\n",
    "        plt.scatter(irisFeature[i, 1], irisFeature[i, 2], c=\"r\", marker=\"v\")\n",
    "    else:\n",
    "        plt.scatter(irisFeature[i, 1], irisFeature[i, 2], c=\"g\", marker=\"8\")\n",
    "plt.plot(xx, yy)             # 绘制分界线\n",
    "plt.xlabel('花萼宽度')\n",
    "plt.ylabel('花瓣长度')\n",
    "plt.show()  # 绘制分类图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
